www.gusucode.com > VC++ 机器人语音控制系统 > VC++ 机器人语音控制系统/gusucode/ROBOT/robotDoc.cpp
//Download by http://www.NewXing.com // robotDoc.cpp : implementation of the CRobotDoc class // #include "stdafx.h" #include "robot.h" #include"SetupDlg.h" #include "robotDoc.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CRobotDoc IMPLEMENT_DYNCREATE(CRobotDoc, CDocument) BEGIN_MESSAGE_MAP(CRobotDoc, CDocument) //{{AFX_MSG_MAP(CRobotDoc) ON_COMMAND(ID_SETUPCOMM, OnSetupcomm) ON_COMMAND(ID_CLOSECOMM, OnClosecomm) ON_COMMAND(ID_OPENCOMM, OnOpencomm) ON_UPDATE_COMMAND_UI(ID_OPENCOMM, OnUpdateOpencomm) ON_UPDATE_COMMAND_UI(ID_CLOSECOMM, OnUpdateClosecomm) ON_COMMAND(ID_ANJIANCTRL, OnAnjianctrl) ON_UPDATE_COMMAND_UI(ID_ANJIANCTRL, OnUpdateAnjianctrl) ON_COMMAND(ID_VOICECTRL, OnVoicectrl) ON_UPDATE_COMMAND_UI(ID_VOICECTRL, OnUpdateVoicectrl) ON_COMMAND(ID_HELP, OnHelp) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CRobotDoc construction/destruction CRobotDoc::CRobotDoc() { // TODO: add one-time construction code here m_bConnected=FALSE; m_pThread=NULL; m_nBaud =244; m_nDataBits = 8; m_nParity = 1; m_sPort = "COM1"; m_nStopBits = 0; m_bctrlmodal=FALSE; m_uCurrentBtn=ID_CLOSECOMM; } CRobotDoc::~CRobotDoc() { if(m_bConnected) CloseConnection(); // 删除事件句柄 if(m_hPostMsgEvent) CloseHandle(m_hPostMsgEvent); if(m_osRead.hEvent) CloseHandle(m_osRead.hEvent); if(m_osWrite.hEvent) CloseHandle(m_osWrite.hEvent); } BOOL CRobotDoc::OnNewDocument() { if (!CDocument::OnNewDocument()) return FALSE; // TODO: add reinitialization code here // (SDI documents will reuse this document) // 为WM_COMMNOTIFY消息创建事件对象,手工重置,初始化为有信号的 if((m_hPostMsgEvent=CreateEvent(NULL, TRUE, TRUE, NULL))==NULL) return FALSE; memset(&m_osRead, 0, sizeof(OVERLAPPED)); memset(&m_osWrite, 0, sizeof(OVERLAPPED)); // 为重叠读创建事件对象,手工重置,初始化为无信号的 if((m_osRead.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL))==NULL) return FALSE; // 为重叠写创建事件对象,手工重置,初始化为无信号的 if((m_osWrite.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL))==NULL) return FALSE; return TRUE; } ///////////////////////////////////////////////////////////////////////////// // CRobotDoc serialization void CRobotDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { // TODO: add storing code here } else { // TODO: add loading code here } } ///////////////////////////////////////////////////////////////////////////// // CRobotDoc diagnostics #ifdef _DEBUG void CRobotDoc::AssertValid() const { CDocument::AssertValid(); } void CRobotDoc::Dump(CDumpContext& dc) const { CDocument::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CRobotDoc commands void CRobotDoc::OnSetupcomm() { // TODO: Add your command handler code here CSetupDlg dlg; CString str; dlg.m_bConnected=m_bConnected; dlg.m_sPort=m_sPort; str.Format("%d",m_nBaud); dlg.m_sBaud=str; str.Format("%d",m_nDataBits); dlg.m_sDataBits=str; dlg.m_nParity=m_nParity; dlg.m_nStopBits=m_nStopBits; //dlg.m_nFlowCtrl=m_nFlowCtrl; //dlg.m_bEcho=m_bEcho; // dlg.m_bNewLine=m_bNewLine; if(dlg.DoModal()==IDOK) { m_sPort=dlg.m_sPort; m_nBaud=atoi(dlg.m_sBaud); m_nDataBits=atoi(dlg.m_sDataBits); m_nParity=dlg.m_nParity; m_nStopBits=dlg.m_nStopBits; // m_nFlowCtrl=dlg.m_nFlowCtrl; // m_bEcho=dlg.m_bEcho; // m_bNewLine=dlg.m_bNewLine; if(m_bConnected) if(!ConfigConnection()) AfxMessageBox("Can't realize the settings!"); } } void CRobotDoc::OnClosecomm() { // TODO: Add your command handler code here m_uCurrentBtn=ID_CLOSECOMM; CloseConnection(); } void CRobotDoc::OnOpencomm() { // TODO: Add your command handler code here m_uCurrentBtn=ID_OPENCOMM; if(!OpenConnection()) AfxMessageBox("Can't open connection"); } void CRobotDoc::OnUpdateOpencomm(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here //pCmdUI->Enable(!m_bConnected); pCmdUI->SetRadio(pCmdUI->m_nID == m_uCurrentBtn); } void CRobotDoc::OnUpdateClosecomm(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here // pCmdUI->Enable(m_bConnected); pCmdUI->SetRadio(pCmdUI->m_nID == m_uCurrentBtn); } void CRobotDoc::OnAnjianctrl() { // TODO: Add your command handler code here } void CRobotDoc::OnUpdateAnjianctrl(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here } void CRobotDoc::OnVoicectrl() { // TODO: Add your command handler code here // WinExec(NULL,NULL,_T("dutty.exe"),NULL,_T("D:\\Program Files\\Dutty\\Dutty.exe"),NULL); WinExec(_T("D:\\Program Files\\Dutty\\Dutty.exe"),SW_SHOW); m_bctrlmodal=TRUE; //STARTUPINFO stinfo; //启动窗口的信息 //PROCESSINFO procinfo; //进程的信息 //CreateProcess(NULL,_T("dutty.exe"),NULL,NULL.FALSE, NORMAL_PRIORITY_ CLASS,NULL,NULL, &stinfo,&procinfo); } void CRobotDoc::OnUpdateVoicectrl(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here pCmdUI->Enable(!m_bctrlmodal); } UINT CommProc(LPVOID pParam) { OVERLAPPED os; DWORD dwMask, dwTrans; COMSTAT ComStat; DWORD dwErrorFlags; CRobotDoc *pDoc=(CRobotDoc*)pParam; memset(&os, 0, sizeof(OVERLAPPED)); os.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL); if(os.hEvent==NULL) { AfxMessageBox("Can't create event object!"); return (UINT)-1; } while(pDoc->m_bConnected) { ClearCommError(pDoc->m_hCom,&dwErrorFlags,&ComStat); if(ComStat.cbInQue) //查询输入缓冲区中是否有字符 ,若有 { // 等待WM_COMMNOTIFY消息被处理完 WaitForSingleObject(pDoc->m_hPostMsgEvent, INFINITE); ResetEvent(pDoc->m_hPostMsgEvent); PostMessage(pDoc->m_hTermWnd, WM_COMMNOTIFY, EV_RXCHAR, 0); // 通知视图 continue; } dwMask=0; if(!WaitCommEvent(pDoc->m_hCom, &dwMask, &os)) // 重叠操作 { //通信事件 if(GetLastError()==ERROR_IO_PENDING) // 无限等待重叠操作结果 GetOverlappedResult(pDoc->m_hCom, &os, &dwTrans, TRUE); else { CloseHandle(os.hEvent); return (UINT)-1; } } } CloseHandle(os.hEvent); return 0; } BOOL CRobotDoc::OpenConnection() { COMMTIMEOUTS TimeOuts; POSITION firstViewPos; CView *pView; firstViewPos=GetFirstViewPosition(); pView=GetNextView(firstViewPos); m_hTermWnd=pView->GetSafeHwnd(); if(m_bConnected) return FALSE; m_hCom=CreateFile(m_sPort, GENERIC_READ|GENERIC_WRITE,0,NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, NULL); // 重叠方式 if(m_hCom==INVALID_HANDLE_VALUE) //AfxMessageBox("dfhksdjfhsjkfhks",MB_OK); return FALSE; SetupComm(m_hCom,1024,1024); SetCommMask(m_hCom, EV_RXCHAR);///////////////////!!!!!!!!!!! // 把间隔超时设为最大,把总超时设为0将导致ReadFile立即返回并完成操作 TimeOuts.ReadIntervalTimeout=MAXDWORD; TimeOuts.ReadTotalTimeoutMultiplier=0; TimeOuts.ReadTotalTimeoutConstant=0; /* 设置写超时以指定WriteComm成员函数中的 GetOverlappedResult函数的等待时间*/ TimeOuts.WriteTotalTimeoutMultiplier=50; TimeOuts.WriteTotalTimeoutConstant=2000; SetCommTimeouts(m_hCom, &TimeOuts); if(ConfigConnection()) { m_pThread=AfxBeginThread(CommProc, this, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED, NULL); // 创建并挂起线程 if(m_pThread==NULL) { CloseHandle(m_hCom); return FALSE; } else { m_bConnected=TRUE; m_pThread->ResumeThread(); // 恢复线程运行 } } else { CloseHandle(m_hCom); return FALSE; } return TRUE; } void CRobotDoc::CloseConnection() { if(!m_bConnected) return; m_bConnected=FALSE; //结束CommProc线程中WaitSingleObject函数的等待 SetEvent(m_hPostMsgEvent); //结束CommProc线程中WaitCommEvent的等待 SetCommMask(m_hCom, 0); //等待辅助线程终止 WaitForSingleObject(m_pThread->m_hThread, INFINITE); m_pThread=NULL; CloseHandle(m_hCom); } BOOL CRobotDoc::ConfigConnection()///设置DCB { DCB dcb; if(!GetCommState(m_hCom, &dcb)) return FALSE; dcb.fBinary=TRUE; dcb.BaudRate=m_nBaud; // 波特率 dcb.ByteSize=m_nDataBits; // 每字节位数 dcb.fParity=TRUE; switch(m_nParity) // 校验设置 { case 0: dcb.Parity=NOPARITY; break; case 1: dcb.Parity=EVENPARITY; break; case 2: dcb.Parity=ODDPARITY; break; default:; } switch(m_nStopBits) // 停止位 { case 0: dcb.StopBits=ONESTOPBIT; break; case 1: dcb.StopBits=ONE5STOPBITS; break; case 2: dcb.StopBits=TWOSTOPBITS; break; default:; } // 硬件流控制设置 // dcb.fOutxCtsFlow=m_nFlowCtrl==1; // dcb.fRtsControl=m_nFlowCtrl==1?RTS_CONTROL_HANDSHAKE:RTS_CONTROL_ENABLE; // XON/XOFF流控制设置 // dcb.fInX=dcb.fOutX=m_nFlowCtrl==2; // dcb.XonChar=XON; // dcb.XoffChar=XOFF; // dcb.XonLim=50; // dcb.XoffLim=50; return SetCommState(m_hCom, &dcb); } DWORD CRobotDoc::ReadComm(unsigned char *buf,DWORD dwLength) { DWORD length=0; COMSTAT ComStat; DWORD dwErrorFlags; ClearCommError(m_hCom,&dwErrorFlags,&ComStat); // 清除错误标志 length=min(dwLength, ComStat.cbInQue); ReadFile(m_hCom,buf,length,&length,&m_osRead);// 将指定数量的字符从串行口输出 return length; } // 将指定数量的字符从串行口输出 DWORD CRobotDoc::WriteComm(unsigned char *buf,DWORD dwLength) { BOOL fState; DWORD length=dwLength; COMSTAT ComStat; DWORD dwErrorFlags; ClearCommError(m_hCom,&dwErrorFlags,&ComStat); // 清除错误标志 fState=WriteFile(m_hCom,buf,length,&length,&m_osWrite); if(!fState){ if(GetLastError()==ERROR_IO_PENDING) { GetOverlappedResult(m_hCom,&m_osWrite,&length,TRUE);// 等待 } else length=0; } return length; } // 工作者线程,负责监视串行口 void CRobotDoc::OnHelp() { // TODO: Add your command handler code here //ShellExecute(NULL,NULL,_T("Jqrhelp.chm"),NULL,_T("e:\\机器人"),NULL); }